home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK2.toast / Development Kits (Disc 2) / QuickTime / Programming Stuff / Documentation / develop articles / develop Issue 23 / Internet Config / IC 1.1 / ICAppSourceKit1.1 / ICHelperWhat.p < prev    next >
Encoding:
Text File  |  1997-02-26  |  14.9 KB  |  537 lines  |  [TEXT/PJMM]

  1. unit ICHelperWhat;
  2.  
  3. interface
  4.  
  5.     uses
  6.         ICWindowGlobals;
  7.  
  8.     function WhatOpenHelper (wt: WindowType; item: integer): OSErr;
  9.     function WhatActivateHelper (wt: WindowType; item: integer; activate: boolean): OSErr;
  10.     function WhatFlushHelper (wt: WindowType; item: integer): OSErr;
  11.     function WhatCloseHelper (wt: WindowType; item: integer): OSErr;
  12.     function WhatClickHelper (wt: WindowType; item: integer; er: eventRecord): OSErr;
  13.     function WhatKeyHelper (wt: WindowType; item: integer; er: EventRecord): OSErr;
  14.     function WhatCursorHelper (wt: WindowType; item: integer; pt: Point; cursorid: integer): OSErr;
  15.  
  16. implementation
  17.  
  18.     uses
  19.         IconFamilies, ICStrH, 
  20.  
  21.         ICKeys, ICAPI, ICSubs, ICDialogs, ICMiscSubs, ICDocUtils, ICGlobals, {}
  22.         ICIConSuites, ICStandardFile, ICMovableModal;
  23.  
  24.     const
  25.         ditChange = 1;
  26.         ditMainUserItem = 2;
  27.         ditAdd = 3;
  28.         ditDelete = 4;
  29.         ditList = 5;
  30.  
  31.     const
  32.         ditOK = 1;
  33.         ditCancel = 2;
  34.         ditAddUserItem = 3;
  35.         ditHelper = 4;
  36.         ditAppName = 5;
  37.         ditChooseApplication = 6;
  38.  
  39.     const
  40.         kCellHeight = 36;
  41.  
  42.     type
  43.         InternalAppSpec = record
  44.                 key: Str255;
  45.                 locked: boolean;
  46.                 appspec: ICAppSpec;
  47.             end;
  48.  
  49.     procedure GetNthElement (entries: Handle; index: integer; var res: InternalAppSpec);
  50.     begin
  51.         BlockMove(Ptr(longint(entries^) + (index - 1) * sizeof(InternalAppSpec)), @res, sizeof(InternalAppSpec));
  52.     end; (* GetNthElement *)
  53.  
  54.     procedure SetNthElement (entries: Handle; index: integer; var res: InternalAppSpec);
  55.     begin
  56.         BlockMove(@res, Ptr(longint(entries^) + (index - 1) * sizeof(InternalAppSpec)), sizeof(InternalAppSpec));
  57.     end; (* SetNthElement *)
  58.  
  59.     function EntryLocked (entries: Handle; index: integer): boolean;
  60.         var
  61.             appspec: InternalAppSpec;
  62.     begin
  63.         GetNthElement(entries, index, appspec);
  64.         EntryLocked := appspec.locked;
  65.     end; (* EntryLocked *)
  66.  
  67.     procedure DimButtons (wt: WindowType);
  68.         var
  69.             have_selection: boolean;
  70.             dlg: DialogPtr;
  71.             selection: integer;
  72.             entries: Handle;
  73.             lh: ListHandle;
  74.     begin
  75.         dlg := windowinfo[wt].window;
  76.         lh := ListHandle(windowinfo[wt].items[ditList]^.spare_data);
  77.         entries := Handle(windowinfo[wt].items[ditList]^.data);
  78.         selection := SelectedLine(lh);
  79.         have_selection := (selection <> -1);
  80.         SetDCtlEnable(dlg, ditAdd, not IsDocLocked);
  81.         SetDCtlEnable(dlg, ditDelete, have_selection and not EntryLocked(entries, selection + 1));
  82.         SetDCtlEnable(dlg, ditChange, have_selection and not EntryLocked(entries, selection + 1));
  83.         OutlineDefault1(dlg, ditMainUserItem);
  84.     end; (* DimButtons *)
  85.  
  86.     procedure UserItemUpdate (dlg: DialogPtr; item: integer);
  87.         var
  88.             list_rect: Rect;
  89.     begin
  90.         GetDItemRect(dlg, item, list_rect);
  91.         PenNormal;
  92.         InsetRect(list_rect, -1, -1);
  93.         FrameRect(list_rect);
  94.         LUpdate(dlg^.visRgn, ListHandle(windowinfo[GetWindowType(dlg)].items[item]^.spare_data));
  95.     end; (* UserItemUpdate *)
  96.  
  97.     procedure MyLDEF (message: integer; select: boolean; var r: Rect; the_cell: Cell; offset: integer; datalen: integer; lh: ListHandle);
  98.         var
  99.             entries: Handle;
  100.  
  101.         procedure LDDraw;
  102.             const
  103.                 HiliteMode = $938;
  104.             var
  105.                 appspec: InternalAppSpec;
  106.                 pos: longint;
  107.                 err: OSErr;
  108.                 junkpos: longint;
  109.                 suite: Handle;
  110.                 cur_x: integer;
  111.                 junk: OSErr;
  112.                 tmprect: Rect;
  113.                 sys_font_info: FontInfo;
  114.                 top: integer;
  115.                 transfer: integer;
  116.                 rgn: RgnHandle;
  117.                 rgn2: RgnHandle;
  118.         begin
  119.             if datalen = 0 then begin
  120.                 GetNthElement(entries, the_cell.v + 1, appspec);
  121.                 EraseRect(r);
  122.                 cur_x := 0;
  123.                 rgn := NewRgn;
  124.                 if system7 then begin
  125.                     tmprect := r;
  126.                     tmprect.bottom := tmprect.top + 32;
  127.                     tmprect.right := tmprect.left + 32;
  128.                     OffsetRect(tmprect, (kCellHeight - 32) div 2, (kCellHeight - 32) div 2);
  129.                     junk := GetDTDBIconSuiteCached('APPL', appspec.appspec.fCreator, suite);
  130.                     if suite <> nil then begin
  131.                         if select then begin
  132.                             transfer := ttSelected;
  133.                         end
  134.                         else begin
  135.                             transfer := ttNone;
  136.                         end; (* if *)
  137.                         err := PlotIconSuite(tmprect, atNone, transfer, suite);
  138.                         junk := IconSuiteToRgn(rgn, tmprect, atNone, suite);
  139.                     end; (* if *)
  140.                     cur_x := cur_x + kCellHeight;
  141.                 end;
  142.                 cur_x := cur_x + 2;
  143.  
  144.                 TextFont(systemFont);
  145.                 GetFontInfo(sys_font_info);
  146.  
  147.                 top := (kCellHeight - (sys_font_info.ascent + sys_font_info.descent)) div 2;
  148.                 TextFont(systemFont);
  149.                 MoveTo(r.left + cur_x, r.top + top + sys_font_info.ascent);
  150.                 DrawString(concat(copy(appspec.key, length(kICHelper) + 1, 255), GetAString(128, 5), appspec.appspec.name));
  151.  
  152.                 if select then begin
  153.                     rgn2 := NewRgn;
  154.                     RectRgn(rgn2, r);
  155.                     if has_colorQD then begin
  156.                         BitClr(Ptr(HiliteMode), pHiliteBit);
  157.                     end; (* if *)
  158.                     XorRgn(rgn, rgn2, rgn2);
  159.                     InvertRgn(rgn2);
  160.                     DisposeRgn(rgn2);
  161.                 end; (* if *)
  162.                 if rgn <> nil then begin
  163.                     DisposeRgn(rgn);
  164.                 end; (* if *)
  165.             end; (* if *)
  166.         end;
  167.  
  168.     begin
  169.         SetPort(lh^^.port);
  170.         entries := Handle(windowinfo[GetWindowType(lh^^.port)].items[ditList]^.data);
  171.         case message of
  172.             lInitMsg: 
  173.                 ;
  174.             lDrawMsg: 
  175.                 LDDraw;
  176.             lHiliteMsg: 
  177.                 LDDraw;
  178.             lCloseMsg: 
  179.                 ;
  180.             otherwise
  181.                 ;
  182.         end;
  183.     end; (* MyLDEF *)
  184.  
  185.     function WhatOpenHelper (wt: WindowType; item: integer): OSErr;
  186.         var
  187.             dlg: DialogPtr;
  188.             entries: Handle;
  189.             attr: longint;
  190.             err: OSErr;
  191.             count: longint;
  192.             list_rect: Rect;
  193.             data_rect: Rect;
  194.             cell_size: Point;
  195.             lh: ListHandle;
  196.             tmpapspec: InternalAppSpec;
  197.             ndx: longint;
  198.             size: longint;
  199.     begin
  200.         err := noErr;
  201.         windowinfo[wt].items[item]^.spare_data := nil;
  202.         windowinfo[wt].items[item]^.data := nil;
  203.         dlg := windowinfo[wt].window;
  204.         SetDItemHandle(dlg, item, @UserItemUpdate);
  205.         entries := NewHandle(0);
  206.         if entries = nil then begin
  207.             err := memFullErr;
  208.         end; (* if *)
  209.         if err = noErr then begin
  210.             ndx := 1;
  211.             repeat
  212.                 err := ICMapErr(ICGetIndPref(GetInstance, ndx, tmpapspec.key));
  213.                 if err = noErr then begin
  214.                     if IUEqualString(copy(tmpapspec.key, 1, length(kICHelper)), kICHelper) = 0 then begin
  215.                         size := sizeof(tmpapspec.appspec);
  216.                         err := ICMapErr(ICGetPref(GetInstance, tmpapspec.key, attr, @tmpapspec.appspec, size));
  217.                         if err = noErr then begin
  218.                             tmpapspec.locked := btst(attr, ICattr_locked_bit) | IsDocLocked;
  219.                             err := PtrAndHand(@tmpapspec, entries, sizeof(InternalAppSpec));
  220.                         end; (* if *)
  221.                     end; (* if *)
  222.                 end; (* if *)
  223.                 ndx := ndx + 1;
  224.             until err <> noErr;
  225.         end; (* if *)
  226.         if err = icPrefNotFoundErr then begin
  227.             err := noErr;
  228.         end; (* if *)
  229.         if err = noErr then begin
  230.             count := GetHandleSize(entries) div sizeof(InternalAppSpec);
  231.             windowinfo[wt].items[item]^.data := Ptr(entries);
  232.             GetDItemRect(dlg, item, list_rect);
  233.             list_rect.right := list_rect.right - 15;
  234.             SetRect(data_rect, 0, 0, 1, count);
  235.             SetPt(cell_size, list_rect.right - list_rect.left, kCellHeight);
  236.             lh := LNew(list_rect, data_rect, cell_size, 128, dlg, true, false, false, true);
  237.             if lh = nil then begin
  238.                 err := memFullErr;
  239.             end; (* if *)
  240.         end; (* if *)
  241.         if err = noErr then begin
  242.             lh^^.refCon := ord(@MyLDEF);
  243.             lh^^.selFlags := lOnlyOne;
  244.             windowinfo[wt].items[item]^.spare_data := Ptr(lh);
  245.             DimButtons(wt);
  246.             SetUpDefaultOutline(dlg, ditChange, ditMainUserItem);
  247.             windowinfo[wt].selected_item := ditList;
  248.         end; (* if *)
  249.         WhatOpenHelper := err;
  250.     end; (* WhatOpenHelper *)
  251.  
  252.     function ChooseApplication (var spec: ICAppSpec): boolean;
  253.         var
  254.             valid: boolean;
  255.             info: FInfo;
  256.             fs: FSSpec;
  257.             err: OSErr;
  258.     begin
  259.         err := ICStandardGetFile('APPL', fs, info);
  260.         DisplayError(acChooseApplication, err);
  261.         if err = noErr then begin
  262.             spec.fCreator := info.fdCreator;
  263.             spec.name := fs.name;
  264.         end; (* if *)
  265.         ChooseApplication := err = noErr;
  266.     end; (* ChooseApplication *)
  267.  
  268.     procedure FixButton (dlg: DialogPtr);
  269.         var
  270.             t1, t2: Str255;
  271.     begin
  272.         GetItemText(dlg, ditAppName, t1);
  273.         GetItemText(dlg, ditHelper, t2);
  274.         SetDCtlEnable(dlg, ditOK, (t1 <> '') and (t2 <> ''));
  275.         OutlineDefault1(dlg, ditAddUserItem);
  276.     end; (* FixButton *)
  277.  
  278.     function DoAddFilter (dlg: DialogPtr; var event: EventRecord; var item: integer): boolean;
  279.         var
  280.             res: boolean;
  281.     begin
  282.         res := CancelModalFilter(dlg, event, item);
  283.         FixButton(dlg);
  284.         DoAddFilter := res;
  285.     end;(* DoAddFilter *)
  286.  
  287.     function DoEdit (entries: Handle; lh: ListHandle; var choosen_app: InternalAppSpec): OSErr;
  288.         var
  289.             dlg: DialogPtr;
  290.             item: integer;
  291.             junk: integer;
  292.             err: OSErr;
  293.             saved_state: Ptr;
  294.     begin
  295.         err := noErr;
  296.         dlg := GetNewDialog(800, nil, WindowPtr(-1));
  297.         if dlg = nil then begin
  298.             err := memFullErr;
  299.         end; (* if *)
  300.         if err = noErr then begin
  301.             SetUpDefaultOutline(dlg, ditOK, ditAddUserItem);
  302.             SetItemText(dlg, ditHelper, choosen_app.key);
  303.             SetItemText(dlg, ditAppName, choosen_app.appspec.name);
  304.             SelIText(dlg, ditHelper, 0, 255);
  305.             FixButton(dlg);
  306.             ShowWindow(dlg);
  307.             DisableMenuBar(saved_state, -1);
  308.             InitCursor;
  309.             repeat
  310.                 MovableModalDialog(@DoAddFilter, item);
  311.                 case item of
  312.                     ditChooseApplication:  begin
  313.                         if ChooseApplication(choosen_app.appspec) then begin
  314.                             SetItemText(dlg, ditAppName, choosen_app.appspec.name);
  315.                             FixButton(dlg);
  316.                         end; (* if *)
  317.                     end;
  318.                     otherwise
  319.                         ;
  320.                 end; (* case *)
  321.             until item in [ditOK, ditCancel];
  322.             if item = ditOK then begin
  323.                 GetItemText(dlg, ditHelper, choosen_app.key);
  324.                 choosen_app.key := concat(kICHelper, choosen_app.key);
  325.             end
  326.             else begin
  327.                 err := userCanceledErr;
  328.             end; (* if *)
  329.             ReEnableMenuBar(saved_state);
  330.             DisposeDialog(dlg);
  331.         end; (* if *)
  332.         DoEdit := err;
  333.     end;
  334.  
  335.     function DoAdd (entries: Handle; lh: ListHandle): OSErr;
  336.         var
  337.             choosen_app: InternalAppSpec;
  338.             dlg: DialogPtr;
  339.             item: integer;
  340.             junk: integer;
  341.             err: OSErr;
  342.     begin
  343.         choosen_app.appspec.name := '';
  344.         choosen_app.key := '';
  345.         err := DoEdit(entries, lh, choosen_app);
  346.         if err = noErr then begin
  347.             err := PtrAndHand(@choosen_app, entries, sizeof(choosen_app));
  348.             if err = noErr then begin
  349.                 junk := LAddRow(1, 32767, lh);
  350.             end; (* if *)
  351.         end;
  352.         DoAdd := err;
  353.     end; (* DoAdd *)
  354.  
  355.     function DoChange (selection: integer; entries: Handle; lh: ListHandle): OSErr;
  356.         var
  357.             err: OSErr;
  358.             tmpspec: InternalAppSpec;
  359.     begin
  360.         GetNthElement(entries, selection + 1, tmpspec);
  361.         Delete(tmpspec.key, 1, length(kICHelper));
  362.         err := DoEdit(entries, lh, tmpspec);
  363.         if err = noErr then begin
  364.             SetNthElement(entries, selection + 1, tmpspec);
  365.             err := noErr;
  366.         end
  367.         else begin
  368.             err := userCanceledErr;
  369.         end; (* if *)
  370.         DoChange := err;
  371.     end; (* DoChange *)
  372.  
  373.     function DoDelete (selection: integer; entries: Handle; lh: ListHandle): OSErr;
  374.         var
  375.             err: OSErr;
  376.             apspec: InternalAppSpec;
  377.             pos: longint;
  378.             junk: OSErr;
  379.     begin
  380.         err := ICMapErr(ICBegin(GetInstance, icReadWritePerm));
  381.         if err = noErr then begin
  382.             GetNthElement(entries, selection + 1, apspec);
  383.             err := ICDeletePref(GetInstance, apspec.key);
  384.             junk := ICMapErr(ICEnd(GetInstance));
  385.         end; (* if *)
  386.         if err = noErr then begin
  387.             pos := Munger(entries, selection * sizeof(InternalAppSpec), nil, sizeof(InternalAppSpec), Ptr(-1), 0);
  388.             err := MemError;
  389.             if err = noErr then begin
  390.                 LDelRow(1, selection, lh);
  391.             end; (* if *)
  392.         end; (* if *)
  393.         DoDelete := err;
  394.     end; (* DoDelete *)
  395.  
  396.     function WhatClickHelper (wt: WindowType; item: integer; er: eventRecord): OSErr;
  397.         var
  398.             lh: ListHandle;
  399.             entries: Handle;
  400.             selection: integer;
  401.             err: OSErr;
  402.             pos: longint;
  403.             r: Rect;
  404.     begin
  405.         entries := Handle(windowinfo[wt].items[ditList]^.data);
  406.         lh := ListHandle(windowinfo[wt].items[ditList]^.spare_data);
  407.         GlobalToLocal(er.where);
  408.         selection := SelectedLine(lh);
  409.         err := 1;
  410.         case item of
  411.             ditAdd: 
  412.                 err := DoAdd(entries, lh);
  413.             ditChange: 
  414.                 err := DoChange(selection, entries, lh);
  415.             ditDelete: 
  416.                 if selection <> -1 then begin
  417.                     err := DoDelete(selection, entries, lh);
  418.                 end; (* if *)
  419.             ditList:  begin
  420.                 if LClick(er.where, 0, lh) then begin
  421.                     selection := SelectedLine(lh);            (* selection may have been changed by LClick *)
  422.                     if EntryLocked(entries, selection + 1) then begin
  423.                         LockedAlert(wt, item);
  424.                         err := userCanceledErr;
  425.                     end
  426.                     else begin
  427.                         FlashItem(windowinfo[wt].window, ditChange);
  428.                         err := DoChange(selection, entries, lh);
  429.                     end; (* if *)
  430.                 end; (* if *)
  431.             end;
  432.         end; (* case *)
  433.         if err = noErr then begin
  434.             DirtyDocument;
  435.         end; (* if *)
  436.         if err = 1 then begin
  437.             err := noErr;
  438.         end; (* if *)
  439.         DimButtons(wt);
  440.         WhatClickHelper := err;
  441.     end; (* WhatClickHelper *)
  442.  
  443.     function WhatFlushHelper (wt: WindowType; item: integer): OSErr;
  444.         var
  445.             err: OSerr;
  446.             entries: Handle;
  447.             i: integer;
  448.             appspec: InternalAppSpec;
  449.             junk: OSErr;
  450.             first_err: OSErr;
  451.     begin
  452.         err := noErr;
  453.         entries := Handle(windowinfo[wt].items[ditList]^.data);
  454.         first_err := noErr;
  455.         for i := 1 to GetHandleSize(entries) div sizeof(InternalAppSpec) do begin
  456.             GetNthElement(entries, i, appspec);
  457.             err := ICMapErr(ICSetPref(GetInstance, appspec.key, ICattr_no_change, @appspec.appspec, sizeof(appspec.appspec)));
  458.             if first_err = noErr then begin
  459.                 first_err := err;
  460.             end; (* if *)
  461.         end; (* for *)
  462.         err := first_err;
  463.         WhatFlushHelper := err;
  464.     end; (* WhatFlushHelper *)
  465.  
  466.     function WhatCloseHelper (wt: WindowType; item: integer): OSErr;
  467.     begin
  468.         LDispose(ListHandle(windowinfo[wt].items[item]^.spare_data));
  469.         DisposeHandle(Handle(windowinfo[wt].items[ditList]^.data));
  470.         WhatCloseHelper := noErr;
  471.     end; (* WhatCloseHelper *)
  472.  
  473.     function WhatActivateHelper (wt: WindowType; item: integer; activate: boolean): OSErr;
  474.     begin
  475.         LActivate(activate, ListHandle(windowinfo[wt].items[item]^.spare_data));
  476.         WhatActivateHelper := noErr;
  477.     end; (* WhatActivateHelper *)
  478.  
  479.     function GetEntryName (list: ListHandle; c: cell): str255;
  480.         var
  481.             appspec: InternalAppSpec;
  482.             entries: handle;
  483.     begin
  484.         GetEntryName := '';
  485.         entries := Handle(windowinfo[GetWindowType(list^^.port)].items[ditList]^.data);
  486.         GetNthElement(entries, c.v + 1, appspec);
  487.         GetEntryName := concat(copy(appspec.key, length(kICHelper) + 1, 255), GetAString(128, 5), appspec.appspec.name);
  488.     end;
  489.  
  490.     function WhatKeyHelper (wt: WindowType; item: integer; er: EventRecord): OSErr;
  491.         var
  492.             ch: integer;
  493.             lh: ListHandle;
  494.             err: OSErr;
  495.             entries: Handle;
  496.             selection: integer;
  497.     begin
  498.         err := noErr;
  499.         if (er.what = keyDown) or (er.what = autoKey) then begin
  500.             ch := BAND(er.message, $FF);
  501.             case ch of
  502.                 crChar, enterChar:  begin
  503.                     if GetDCtlEnable(windowinfo[wt].window, ditChange) then begin
  504.                         entries := Handle(windowinfo[wt].items[ditList]^.data);
  505.                         lh := ListHandle(windowinfo[wt].items[item]^.spare_data);
  506.                         selection := SelectedLine(lh);
  507.                         FlashItem(windowinfo[wt].window, ditChange);
  508.                         err := DoChange(selection, entries, lh);
  509.                         if err = noErr then begin
  510.                             DirtyDocument;
  511.                         end;
  512.                     end;
  513.                 end;
  514.                 otherwise begin
  515.                     DoListKey(ListHandle(windowinfo[wt].items[item]^.spare_data), er.modifiers, chr(BAND(er.message, $FF)), @GetEntryName);
  516.                     DimButtons(wt);
  517.                 end;
  518.             end;
  519.         end;
  520.         WhatKeyHelper := err;
  521.     end; (* WhatKeyHelper *)
  522.  
  523.     function WhatCursorHelper (wt: WindowType; item: integer; pt: Point; cursorid: integer): OSErr;
  524.         var
  525.             r: Rect;
  526.     begin
  527.         GetDItemRect(windowinfo[wt].window, item, r);
  528.         InsetRect(r, 15, 0);
  529.         if PtInRect(pt, r) then begin
  530.             SetCursor(GetCursor(cursorid)^^);
  531.         end
  532.         else begin
  533.             InitCursor;
  534.         end; (* if *)
  535.     end; (* WhatCursorHelper *)
  536.  
  537. end. (* ICHelperWhat *)